package controller

import (
	"fmt"
	"gitee.com/saxon134/go-utils/saData"
	"gitee.com/saxon134/go-utils/saData/saHit"
	"gitee.com/saxon134/go-utils/saOrm"
	"gitee.com/saxon134/workflow/api"
	"gitee.com/saxon134/workflow/db"
	"gitee.com/saxon134/workflow/db/chat"
	"gitee.com/saxon134/workflow/db/job"
	"gitee.com/saxon134/workflow/db/user"
	"gitee.com/saxon134/workflow/enum"
	"gitee.com/saxon134/workflow/errs"
	"gitee.com/saxon134/workflow/interface/ioJob"
	"strings"
)

func JobList(c *api.Context) (resp *api.Response, err error) {
	var in = new(ioJob.ListRequest)
	c.Bind(in)

	var usrObj = new(user.TblUser)
	db.MySql.Table(user.TBNUser).Where("id = ?", c.Account.Id).First(usrObj)
	if usrObj.Id <= 0 {
		return nil, errs.New(errs.ErrorUnauthorized)
	}

	var ary = make([]*job.TblJob, 0, c.Paging.Limit)
	var query = db.MySql.Table(job.TBNJob)

	if in.DemandId > 0 {
		query.Where("demand_id = ?", in.DemandId).Find(&ary)
	}

	if in.OnlyMe {
		query.Where("leader = ?", usrObj.Id)
	}

	//排序
	if c.Sort.Key != "" {
		var key = saData.SnakeStr(c.Sort.Key)
		query.Order(key + saHit.Str(c.Sort.Desc, " desc", " asc"))
		query.Where(key + " is not null")
	} else
	//默认按优先级
	{
		query.Order("deadline asc, p asc, status asc, id desc")
	}

	//管理员&经理之外，仅能查看自己的任务
	if strings.Contains(usrObj.Roles, "1") == false && strings.Contains(usrObj.Roles, "2") == false {
		query.Where(fmt.Sprintf("leader = %d", c.Account.Id))
	}

	if in.Keyword != "" {
		query.Where(fmt.Sprintf("content like '%%%s%%'", in.Keyword))
	}

	if in.Status != 0 {
		query.Where("status = ?", in.Status)
	} else {
		query.Where("(status in(1,20,30) and deadline is not null)")
	}

	//指定需求，则不分页，一次返回所有
	if in.DemandId > 0 {
		err = query.Find(&ary).Error
		if db.MySql.IsError(err) {
			return nil, errs.New(err)
		}
	} else {
		if c.Paging.Total <= 0 {
			query.Count(&c.Paging.Total)
			if db.MySql.IsError(err) {
				return nil, errs.New(err)
			}
		}

		if c.Paging.Total <= int64(c.Paging.Offset) {
			return &api.Response{Result: nil}, nil
		}

		err = query.Limit(c.Paging.Limit).Offset(c.Paging.Offset).Find(&ary).Error
		if db.MySql.IsError(err) {
			return nil, errs.New(err)
		}
	}

	//组装数据
	var resAry = make([]*ioJob.ListItem, 0, len(ary))
	for _, v := range ary {
		var item = &ioJob.ListItem{
			TblJob: v,
		}
		resAry = append(resAry, item)
	}
	return &api.Response{Result: resAry}, nil
}

func JobSave(c *api.Context) (resp *api.Response, err error) {
	var in = new(job.TblJob)
	c.Bind(in)
	if in.Content == "" {
		return nil, errs.New(errs.ErrorParams)
	}

	if in.Id <= 0 {
		if in.Leader <= 0 {
			in.Leader = c.Account.Id
		}
		in.CreateAt = saOrm.Now()
		if in.Status == 0 {
			in.Status = 1
		}
	}

	if in.ProjectId <= 0 && in.DemandId > 0 {
		db.MySql.Raw("select project_id from demand where id = ?", in.DemandId).Scan(&in.ProjectId)
		if in.ProjectId <= 0 {
			return nil, errs.New("缺少项目ID")
		}
	}

	//相同需求下，不能出现同名且责任人一样的任务
	if in.DemandId > 0 {
		var existId int64
		db.MySql.Raw("select id from job where demand_id = ? and leader = ? and content = ? and status <> -1", in.DemandId, in.Leader, in.Content).Scan(&existId)
		if existId > 0 && existId != in.Id {
			return nil, errs.New(errs.ErrorExisted)
		}
	}

	//任务状态判断
	var jobStatus int
	if in.Id > 0 {
		db.MySql.Raw("select status from job where id = ?", in.Id).Scan(&jobStatus)
		if jobStatus == 2 && in.Status != 2 {
			return nil, errs.New("任务已完成，状态不可变更")
		}
	}

	//完成任务
	if in.Id > 0 && (in.Status == enum.WorkDone || in.Status == enum.WorkOnline) && (jobStatus != enum.WorkDone && jobStatus != enum.WorkOnline) {
		if in.DemandId > 0 {
			//任务来源于需求，则创建一条聊天记录
			var demandStatus int
			db.MySql.Raw("select status from demand where id = ?", in.DemandId).Scan(&demandStatus)

			var content = fmt.Sprintf("完成任务【%s】", saData.SubStr(in.Content, 0, 15)+saHit.Str(saData.StrLen(in.Content) > 15, "...", ""))
			var obj = &chat.TblChat{
				CreateAt:     saOrm.Now(),
				Creator:      c.Account.Id,
				DemandId:     in.DemandId,
				Content:      content,
				DemandStatus: demandStatus,
				Status:       1,
				Level:        1,
			}
			db.MySql.Table(chat.TBNChat).Save(obj)

			//如果关联需求下任务都完成，则需求状态自动变为已完成
			if in.DemandId > 0 {
				var idAry = make([]int64, 0, 10)
				err = db.MySql.Raw("select id from job where demand_id = ? and status in(1,20,30)", in.DemandId).Scan(&idAry).Error
				if db.MySql.IsError(err) == false && len(idAry) == 0 || (len(idAry) == 1 && idAry[0] == in.Id) {
					db.MySql.Exec("update demand set status = 100 where id = ? and status in(1,20,30)", in.DemandId)
				}
			}
		}
		in.DoneAt = saOrm.Now()
	}

	err = db.MySql.Save(in).Error
	if err != nil {
		return nil, errs.New(err)
	}
	return &api.Response{Result: in}, nil
}
